// poj2914
// 题意：给定一个简单无向带边权图，给定一个起点，然后你要选定终点，
//       使得最大流最小。
//
// 题解：注意图中一个割对应一个稳定后的流，所以要使最大流最小，
//       就是找最小割。那么想到全局最小割，不过有个不一样的地方就是
//       给定了源点s。不过没有关系，直接不要管它，套用stoer_wagner算法，
//       求得割集后，s肯定或属于S或属于T，所以还是有对应的t的。
//
// 统计：1996ms, 26min, 1A
//
// run: $exec < input
#include <cstdio>
#include <algorithm>
#include <cstring>

int const inf = 1 << 30;
int const maxn = 505;
int graph[maxn][maxn];
bool merged[maxn];
int n, m;

void merge(int s, int t) // merge t to s
{
	merged[t] = true;
	for (int i = 0; i < n; i++)
		if (!merged[i]) {
			graph[s][i] += graph[t][i];
			graph[i][s] += graph[i][t];
		}
}

bool vis[maxn];
int wet[maxn]; // sigma of weight from v to A, A is the current subset of G

int min_cut_phase(int & s, int & t)
{
	std::memset(vis, 0, sizeof(vis));
	std::memset(wet, 0, sizeof(wet));
	s = t = -1;
	int max, min_cut = inf, pos;
	for (int i = 0; i < n; i++) {
		max = -inf;
		for (int j = 0; j < n; j++)
			if (!merged[j] && !vis[j] && wet[j] > max) {
				pos = j;
				max = wet[j];
			}
		if (t == pos) break;
		s = t; t = pos;
		min_cut = max;
		vis[pos] = true;

		// add current active verticle to A
		for (int j = 0; j < n; j++)
			if (!merged[j] && !vis[j]) wet[j] += graph[pos][j];
	}
	return min_cut;
}

int stoer_wagner()
{
	std::memset(merged, 0, sizeof(merged));
	int ret = inf, s, t;
	for (int i = 1; i < n; i++) {
		int min_cut = min_cut_phase(s, t);
		ret = std::min(ret, min_cut);
		if (!ret) return 0;
		merge(s, t);
	}
	return ret;
}

int main()
{
	int s;
	while (std::scanf("%d %d %d", &n, &m, &s) && (n || m || s)) {
		std::memset(graph, 0, sizeof(graph));
		for (int i = 0, x, y, z; i < m; i++) {
			std::scanf("%d %d %d", &x, &y, &z);
			--x; --y;
			graph[x][y] += z; graph[y][x] += z;
		}
		std::printf("%d\n", stoer_wagner());
	}
}

